#include "Framework.h"

/*Initialize the static variables*/
IDirect3DVertexDeclaration9* Vertex::m_Decl = 0;

/*The default Constructor*/
Framework::Framework(void)
{
	/*Seed the random function to time so we get a better random generation*/
	srand((unsigned)time(0));

	/*Make our Matricies all Identities so they have no values or something random that can affect the start of the game*/
	D3DXMatrixIdentity(&m_WorldMat);
	D3DXMatrixIdentity(&m_WorldInverseTransposeMat);
	D3DXMatrixIdentity(&m_RotMat);
	D3DXMatrixIdentity(&m_ScaMat);
	D3DXMatrixIdentity(&m_TransMat);

	/*Make all of our DataStructures and classes all cleared out*/
	ZeroMemory(&m_Light, sizeof(m_Light));
	ZeroMemory(&m_MaterialOrange, sizeof(m_MaterialOrange));
	ZeroMemory(&m_MaterialNorm, sizeof(m_MaterialNorm));
	ZeroMemory(&m_D3Dpp, sizeof(m_D3Dpp));

	/*Clear out all of our vectors(2D, 3D, and Quaternions) so that they don't start out with random values*/

	/*Clear out all of our normal data types to the default value so that they don't start out with random values*/
	m_LightAttenConst = 0;
	m_LightAttenLinear = 0;
	m_LightAttenQuad = 0;
	m_Fps = 0;
	m_MillSpf = 0;
	m_DT = 0.1f;
	m_DevBehaviorFlags = 0;
	m_Width = 0;
	m_Height = 0;


	/*Clear out all of the Pointers so that they don't point to random locations*/
	m_hWnd = 0;
	m_pD3DObject = 0;
	m_pD3DDevice = 0;
	m_pD3DEffect = 0;
	m_hD3DEffectTechnique = 0;
	//m_hShaderVar = 0;
	m_Grass0Texture = 0;
	m_pSphereMesh = 0;
	m_Font = 0;
	m_KeyDown = 0;

	/*Set the variables that are less than 4 bytes to the default values*/
	m_VSync = false;
	m_ShaderVersion4 = false;
	m_ShaderVersion3 = false;
	m_ShaderVersion2 = false;
}

/*The default Destructor*/
Framework::~Framework(void)
{
	/*Since Shutdown does all of the releasing, and shutdown is being called outside of this
	this does nothing at all*/
}

/*The Initialize function to create all of our objects and things that need to be rendered*/
void Framework::Initialize(HWND hWnd, HINSTANCE hInst, bool bWindowed)
{
	/*Rectangle of our window*/
	RECT r;

	/*Fill up our rectangle with the values that make up the window*/
	GetWindowRect(hWnd, &r);

	/*The width is the difference between the right and the left*/
	m_Width = r.right - r.left;

	/*The height is the difference between the bottom and the top*/
	m_Height = r.bottom - r.top;

	/*Store the Handle to the window locally*/
	m_hWnd = hWnd;

	/*Set that we are not using Vertical Sync*/
	m_VSync = false;

	/*Create and store the Object for our renderer*/
	m_pD3DObject = Direct3DCreate9(D3D_SDK_VERSION); //D3D_SDK_VERSION uses a macro in order to get the version

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/*Using the Presentation parameters object that we have set all of the values so that we create the object that we want*/
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	/*The handle to the window*/
	m_D3Dpp.hDeviceWindow = hWnd;

	/*The bool that checks to see if we are windowed or in full screen*/
	m_D3Dpp.Windowed =	bWindowed;

	/*The number of back buffers that we have in our object*/
	m_D3Dpp.BackBufferCount = 1;

	/*The format for our back buffer(Pixel Format)*/
	m_D3Dpp.BackBufferFormat = D3DFMT_X8R8G8B8;

	/*The height of the back buffer*/
	m_D3Dpp.BackBufferHeight = m_Height;

	/*The width of the back buffer*/
	m_D3Dpp.BackBufferWidth = m_Width;

	/*The effect that happens after swapping with the back buffer*/
	m_D3Dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;

	/*The presentation interval of our object, deals witht the refresh rate of the monitor, If we are using vsync, use the default, if not then show it immediately*/
	m_D3Dpp.PresentationInterval = m_VSync ? D3DPRESENT_INTERVAL_DEFAULT : D3DPRESENT_INTERVAL_IMMEDIATE;

	/*Changes the refresh rate of the screen, If we are in full screen the refresh rate is 0, if not then use the default*/
	m_D3Dpp.FullScreen_RefreshRateInHz = bWindowed ? 0 : D3DPRESENT_RATE_DEFAULT;

	/*Set whether we are using the Depth and/or the stencil buffer in this application*/
	m_D3Dpp.EnableAutoDepthStencil = TRUE;

	/*The format of the depth buffer (Bit Format)*/
	m_D3Dpp.AutoDepthStencilFormat = D3DFMT_D24S8;

	/*Flags we want to have within the presentation parameters, This one discards the depth buffers upon present*/
	m_D3Dpp.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;

	/*The multiSample AntiAliasing quality*/
	m_D3Dpp.MultiSampleQuality = 0;

	/*The type of multiSample AntiAliasing*/
	m_D3Dpp.MultiSampleType = D3DMULTISAMPLE_NONE;

	/*Based on the capabilities of our device determine the things we can and cant do*/
	DetermineCaps();

	/*Now that the capabilites of our device have been found create the device object*/
	m_pD3DObject->CreateDevice(D3DADAPTER_DEFAULT,				//Default display adapter
		D3DDEVTYPE_HAL,					//Device type to use 
		hWnd,							//Handle to our window
		m_DevBehaviorFlags,				//Behavior Flags (PUREDEVICE, HARDWARE_VERTEXPROCESSING, SOFTWARE_VERTEXPROCESSING)
		&m_D3Dpp,						//Presentation Parameters
		&m_pD3DDevice);					//Return a created D3D Device

	/*Now that we have the device, we can create the text object that we will be using*/
	D3DXCreateFont(m_pD3DDevice,								//Device
		18,											//Height
		12,											//Width
		FW_BOLD,										//Weight
		0,											//Mip Levels
		true,										//Italics
		DEFAULT_CHARSET,								//Charset
		OUT_DEFAULT_PRECIS,							//Output Precision
		DEFAULT_QUALITY,								//Quality
		DEFAULT_PITCH | FF_DONTCARE,					//Pitch and Family
		L"Times New Roman",							//FaceName
		&m_Font);									//Font Object

	/*Set the Render State of our device*/
	m_pD3DDevice->SetRenderState(D3DRS_ZENABLE,					//RenderStateType
		D3DZB_TRUE);					//Value

	/*Create the input device*/
	m_Input = new Input(hInst, hWnd);

	/*Store the bool array used with the input device*/
	m_KeyDown = m_Input->getBoolArray();

	/*Initialize our camera*/
	m_Cam.Initialize(m_Height, m_Width, m_Input);

	/*Create the textures we will be using, that aren't in objects, and call the methods within the objects to create the textures*/
	createTextures();

	/*Create the materials we will be using, that aren't in objects, and call the methods within the objects to create the Materials*/
	createMaterials();

	/*Create the lights we will be using, that aren't in objects, and call the methods within the objects to create the Lights*/
	createLights();

	/*Create the meshes we will be using, that aren't in objects, and call the methods within the objects to create the meshes*/
	createMeshes();

	/*Create our effects*/
	createEffects();

	/*Set timer*/
	timer.update();

	/*Make sure all of the matrices are Identity*/
	makeIdentityMatrix();
}

/*The function that will determine what settings we can use to run our game*/
void Framework::DetermineCaps()
{
	/*The current devices capabilities so we know what we can and can't use with direct x*/
	D3DCAPS9 m_D3Dcaps;

	/*Get the device capabilities*/
	m_pD3DObject->GetDeviceCaps(D3DADAPTER_DEFAULT,				//The primary adapter to check
		D3DDEVTYPE_HAL,											//Device type to check
		&m_D3Dcaps);											//pointer to caps object

	/*Checks to see if the device supports Hardware vertex processing*/
	if(m_D3Dcaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
	{
		/*Since it can show that it can do Hardware vertex processing*/
		m_DevBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;

		/*Checks to see if the device supports a pure device type.*/
		if(m_D3Dcaps.DevCaps & D3DDEVCAPS_PUREDEVICE)
		{
			/*Since it can that means that the Device is capable of doing it all on its own*/
			m_DevBehaviorFlags |= D3DCREATE_PUREDEVICE;
		}
	}
	/*If it can't*/
	else 
	{
		/*The it has to do vertex processing through the software*/
		m_DevBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
	}

	/*Check to see which shader versions for pixel and vertex shading the device can support*/
	if(m_D3Dcaps.VertexShaderVersion < D3DVS_VERSION(4, 0))
	{
		/*Since it can't handle Version 4.0 Check version 3.0*/
		if(m_D3Dcaps.VertexShaderVersion < D3DVS_VERSION(3, 0))
		{
			/*Since it can't handle Version 3.0 Check version 2.0*/
			if(m_D3Dcaps.VertexShaderVersion < D3DVS_VERSION(2, 0))
			{
				/*Since it can't handle version 2.0, don't use any shader*/
				m_ShaderVersion2 = false;
			}
			/*Since it can run Shader Version 2.0 Use shader version 2*/
			else
			{
				m_ShaderVersion2 = true;
			}
		}
		/*Since it can run Shader Version 3.0 Use shader version 3*/
		else
		{
			m_ShaderVersion3 = true;
		}
	}
	/*Since it can run Shader Version 4.0 Use shader version 4*/
	else
	{
		m_ShaderVersion4 = true;
	}
	/*TO BE ADDED: More capabilites to be checked. Added as things are required*/
}

/*The function that will create all of the textures that we are going to be using not within any object*/
void Framework::createTextures()
{
	/*Create the textures*/
	D3DXCreateTextureFromFile(m_pD3DDevice,			//The Device
							  L"grass0.dds",		//The file path
							  &m_Grass0Texture);	//Address of the texture
}

/*The function that will create all of the materials that we are going to be using not within any object*/
void Framework::createMaterials()
{
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/*Fill the material Structure up, MATERIAL ORANGE*/
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	/*The ambient color of the material*/
	m_MaterialOrange.Ambient = D3DXCOLOR(0.2f, 0.2f,0.0f,1.0f);

	/*The diffuse color of the material*/
	m_MaterialOrange.Diffuse = D3DXCOLOR(1.0f,0.50196f,0.0f,1.0f);

	/*The specular color of the material*/
	m_MaterialOrange.Specular = D3DXCOLOR(1.0f,1.0f,1.0f,1.0f);

	/*The power of the specular of the material*/
	m_MaterialOrange.Power = 30.0f;

	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/*Fill the material Structure up, MATERIAL NORMAL*/
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	/*The ambient color of the material*/
	m_MaterialNorm.Ambient = D3DXCOLOR(0.2f,0.2f,0.2f,1.0f);

	/*The diffuse color of the material*/
	m_MaterialNorm.Diffuse = D3DXCOLOR(1.0f,1.0f,1.0f,1.0f);

	/*The specular color of the material*/
	m_MaterialNorm.Specular = D3DXCOLOR(0.0f,0.0f,0.0f,0.0f);

	/*The power of the specular of the material*/
	m_MaterialNorm.Power = 0.0f;
}

/*The function that will create all of the lights that we are going to be using not within any object*/
void Framework::createLights()
{
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/*Fill the light Structure up, Light ONE*/
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	/*The ambient color of the material*/
	m_Light.Ambient = D3DXCOLOR(1.0f,1.0f,1.0f,1.0f);

	/*The diffuse color of the material*/
	m_Light.Diffuse = D3DXCOLOR(1.0f,1.0f,1.0f,1.0f);

	/*The specular color of the material*/
	m_Light.Specular = D3DXCOLOR(1.0f,1.0f,1.0f,1.0f);

	/*The type of light*/
	m_Light.Type = D3DLIGHT_POINT;

	/*The position of the light*/
	m_Light.Position = D3DXVECTOR3(30, 30, -50);

	/*The range of the light*/
	m_Light.Range = 100.0f;

	/*The light's constant attenuation (x^0)*/
	m_LightAttenConst = 0.0f;

	/*The light's linear attenuation (x^1)*/
	m_LightAttenLinear = 0.05f;

	/*The light's Quadratic attenuation (x^2)*/
	m_LightAttenQuad = 0.0f;
}

/*The function that will create all of the meshes that we are going to be using not within any object*/
void Framework::createMeshes()
{
	/*Create a VertexElement item to get the Correct declaration*/
	D3DVERTEXELEMENT9 elems[MAX_FVF_DECL_SIZE];

	/*Create a Unsigned int to hold the number of elements*/
	UINT numElems = 0;

	/*Using the declaration get the declaration from the elements and store into the UINT*/
	//Vertex::m_Decl->GetDeclaration(elems, &numElems);

	/*Create a temp mesh pointer to avoid memory leaks*/
	ID3DXMesh* m_pSphereMeshTemp = 0;

	/*Create the mesh that we want*/
	D3DXCreateSphere(m_pD3DDevice,				//The device
					 0.5f,							//The radius of the sphere
					 25,							//The number of slices
					 25,							//The number of stacks
					 &m_pSphereMesh,				//The pointer to the mesh object
					 0);							//The pointer to the adjacency buffer

	/*Create the mesh for Luigi*/
	D3DXCreatePolygon(m_pD3DDevice,				//The device
					 1.0f,							//The length of the polygon
					 4,								//The number of sides
					 &m_pLuigiMesh,				//The pointer to the mesh object
					 0);							//The pointer to the adjacency buffer

	/*Since the mesh created by the D3DXfunctions aren't of the right decl clone the mesh*/
	//m_pSphereMesh->CloneMesh(D3DXMESH_SYSTEMMEM,	//Options
	//						 elems,					//Vertex Declaration
	//						 m_pD3DDevice,			//The Device
	//						 &m_pSphereMeshTemp);		//The pointer to the clone mesh

	///*Delete the old mesh*/
	//SAFE_RELEASE(m_pSphereMesh);

	///*Set the new mesh to the pointer we had earlier*/
	//m_pSphereMesh = m_pSphereMeshTemp;

	/*Call all object related createMeshes*/
}

/*The function that will create all of the effects that we are going to be using not within any object*/
void Framework::createEffects()
{
	/*Create and Store the effect file*/
	D3DXCreateEffectFromFile(m_pD3DDevice,		//The device
							   L"Blinn_Phong_Bump_Reflect.fx",			//The path name
							   0,					//Defines Parameter
							   0,					//Include Parameter
							   D3DXSHADER_DEBUG,	//flag for compiling the shader
							   0,					//EffectPool parameter
							   &m_pD3DEffect,		//Pointer to an ID3DXEffect
							   &m_pD3DEffectError);//Pointer to an ID3DXBuffer that contains errors

	/*If there are any errors created*/
	if(m_pD3DEffectError)
	{
		/*Output the errors*/
		MessageBox(0, (LPCWSTR)m_pD3DEffectError->GetBufferPointer(), 0, 0);
	}

	/*Create and store the handles to the variables within the shader*/
	m_hD3DEffectTechnique = m_pD3DEffect->GetTechniqueByName("Blinn_Phong");
}

/*The function that will make all of the matrices into Identities*/
void Framework::makeIdentityMatrix()
{
	/*Make the world matrix an Identity*/
	D3DXMatrixIdentity(&m_WorldMat);

	/*Make the world inverse transpose matrix an Identity*/
	D3DXMatrixIdentity(&m_WorldInverseTransposeMat);

	/*Make the rotation matrix an Identity*/
	D3DXMatrixIdentity(&m_RotMat);

	/*Make the scaling matrix an Identity*/
	D3DXMatrixIdentity(&m_ScaMat);

	/*Make the translation matrix an Identity*/
	D3DXMatrixIdentity(&m_TransMat);
}

void Framework::Update()
{
	/*Update the delta time in the timer*/
	timer.update();

	/*Get the delta time from the timer*/
	m_DT = timer.getDT();

	/*The variable used to find and display the number of frames that have been updated*/
	static short numFrames = 0;

	/*The variable used to hold the amount of time that has passed*/
	static float timeElapsed = 0.0f;

	/*Increment the amount of frames that have been shown*/
	numFrames += 1;

	/*Add the time*/
	timeElapsed += m_DT;

	/*Check to see if one second has passed*/
	if(timeElapsed >= 1.0f)
	{
		/*The number of frames is frames per second since we are only going
		to one second*/
		m_Fps = numFrames;

		/*Since we are going to one second, the milliseconds per fraom is
		1000 divided by the number of frames per second*/
		m_MillSpf = 1000.0f / m_Fps;

		/*Reset the number of frames for the next second that we are calculating for*/
		numFrames = 0;

		/*Reset the time that has passed for the next second that we are calculating for*/
		timeElapsed = 0;
	}

	float t = timeGetTime() / 800.0f;
	float r = 35.0f;
	m_Light.Position.x = sinf(t) * r;
	m_Light.Position.y = 20.0f;
	m_Light.Position.z = cosf(t) * r;

	/*Update our input*/
	m_Input->acquire();

	/*Update our camera as well*/
	m_Cam.update(m_DT);
}

void Framework::Render()
{
	/*If our D3D Device was not/has not been created*/
	if(!m_pD3DDevice)
	{
		/*Go back to the loop*/
		return;
	}

	/*Clear all of the matrices to identities*/
	makeIdentityMatrix();

	/*Clear the back-buffer*/
	m_pD3DDevice->Clear(0,									//clears the amount of buffers
						0,									//Clears a rect value
						D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,	//clears the entire buffer
						D3DXCOLOR(0.0f,0.4f,0.8f,1.0f),		//sets the color of the screen
						1.0f,								//z-buffer value
						0);									//stencil

	/*The buffer used so that we can display text on screen*/
	static WCHAR buffer[256];

	/*Create the rect that will be used for the location of the text*/
	RECT formatRect = {5,5,0,0};

	/*Begin the rendering process*/
	m_pD3DDevice->BeginScene();

	float attenConst = 0.0f;
	float attenLinear = 0.5f;
	float attenQuad = 0.0f;
	float specular = 30.0f;

	/* Set dynamic shader variables */
	m_pD3DEffect->SetTechnique(m_hD3DEffectTechnique);
	m_pD3DEffect->SetMatrix("WVPXF", &(m_WorldMat * m_Cam.getView() * m_Cam.getProj()));
	m_pD3DEffect->SetMatrix("WorldXF", &m_WorldMat);
	m_pD3DEffect->SetMatrix("WorldITXF", (D3DXMatrixTranspose(&(m_WorldMat),(D3DXMatrixInverse(&m_WorldMat,0,&m_WorldMat)))));
	m_pD3DEffect->SetValue("Light0Pos", &m_Light.Position, sizeof(D3DXVECTOR4));
	m_pD3DEffect->SetTexture("DiffuseTexture", m_Grass0Texture);

	
	m_pD3DEffect->SetValue("EyePosition",&m_Cam.getPos(),sizeof(D3DXVECTOR3));
	m_pD3DEffect->SetValue("Light0ColorAmbient",&D3DXCOLOR(1.0f,1.0f,1.0f,1.0f),sizeof(D3DXCOLOR));
	m_pD3DEffect->SetValue("Light0ColorDiffuse",&D3DXCOLOR(1.0f,1.0f,1.0f,1.0f),sizeof(D3DXCOLOR));
	m_pD3DEffect->SetValue("Light0ColorSpecular",&D3DXCOLOR(1.0f,1.0f,1.0f,1.0f),sizeof(D3DXCOLOR));
	m_pD3DEffect->SetValue("MatAmbientColor",&D3DXCOLOR(0.2f,0.2f,0.2f,1.0f),sizeof(D3DXCOLOR));
	m_pD3DEffect->SetValue("MatDiffuseColor",&D3DXCOLOR(1.0f,1.0f,0.0f,1.0f),sizeof(D3DXCOLOR));
	m_pD3DEffect->SetValue("MatSpecularColor",&D3DXCOLOR(1.0f,1.0f,1.0f,1.0f),sizeof(D3DXCOLOR));
	m_pD3DEffect->SetValue("hasTexture",(void*)true,sizeof(bool));
	
	m_pD3DEffect->SetValue("Light0ConstAtten",&attenConst,sizeof(float));
	m_pD3DEffect->SetValue("Light0LinearAtten",&attenLinear,sizeof(float));
	m_pD3DEffect->SetValue("Light0QuadAtten",&attenQuad,sizeof(float));
	
	m_pD3DEffect->SetValue("SpecularPower",&specular,sizeof(float));

	/* Begin the shader pass(es) */
	UINT Passes;
	m_pD3DEffect->Begin(&Passes, 0);
	for (UINT Pass = 0; Pass < Passes; ++Pass)
	{
		m_pD3DEffect->BeginPass(Pass);

		/* Render Luigi */
		m_pLuigiMesh->DrawSubset(0);

		m_pD3DEffect->EndPass();
	}
	m_pD3DEffect->End();

	/*The integer used to store the amount of characters used by the swprintf_s for formatted strings*/
	int j;

	/*Store the amount of characters used in j to display the frames per second*/
	j = swprintf_s(buffer,								//The array of characters to store the information and starting point
				   256,									//The size of the array
				   L"Frames Per Second = %.2f\n",		//The string to put into the array with formatting
				   m_Fps);								//Any variables that will be placed into the formatted string

	/*Store the amount of characters used in j to display the milliseconds per frame*/
	j += swprintf_s(buffer +j,							//The array of characters to store the information and starting point
					256 - j,							//The size of the array
					L"Milliseconds per frame = %.4f\n",	//The string to put into the array with formatting
					m_MillSpf);							//Any variables that will be placed into the formatted string

	/*Render the text to the screen above everything else*/
	m_Font->DrawTextW(0,				//Sprite Texture
		buffer,							//Text
		-1,								//Count
		&formatRect,					//RECT used for location
		DT_NOCLIP,						//The way you want the text to react on the location
		D3DCOLOR_XRGB(255,255,0));		//Color


	/*End the rendering process in general*/
	m_pD3DDevice->EndScene();

	/*Present the back-buffer to the screen*/
	m_pD3DDevice->Present(0,0,0,0);		//if there is a specific rectangle we want to present add values
	//}
}

/*The function that will make sure we resize correctly*/
void Framework::screenResize()
{
	/*Create a rectangle that will hold the dimensions of our new sized window*/
	RECT clientRect;

	/*Get the rectangle that has the dimensions of our new sized window*/
	GetClientRect(m_D3Dpp.hDeviceWindow,&clientRect);

	/*Set the back buffer height to the height of the window*/
	m_D3Dpp.BackBufferHeight = clientRect.bottom;

	/*Set the back buffer width to the width of the window*/
	m_D3Dpp.BackBufferWidth = clientRect.right;

	/*Change window style to support windowed*/
	SetWindowLongPtr(m_D3Dpp.hDeviceWindow,GWL_STYLE,WS_OVERLAPPEDWINDOW);

	/*To get the change to take effect must call setWindowPos*/
	SetWindowPos(m_D3Dpp.hDeviceWindow, HWND_TOP,100,100,clientRect.right,clientRect.bottom,SWP_NOZORDER | SWP_SHOWWINDOW);

	/*Our device has been lost call the all of our objects on lost device functions*/
	onLostDevice();

	/*Reset our device using the presentation parameters*/
	m_pD3DDevice->Reset(&m_D3Dpp);

	/*Call all of our objects on reset device since our device has been reset*/
	onResetDevice();
}

/*The function that we will use to switch from windowed to full screen and vice versa*/
void Framework::switchingFullScreen(bool enable)
{
	/*If we want to enable full screen*/
	if(enable)
	{
		/*Check to see if we are already in full screen mode*/
		if(!m_D3Dpp.Windowed)
		{
			/*If we are then our work is done*/
			return;
		}

		/*Get the width of the screen*/
		int width = GetSystemMetrics(SM_CXSCREEN);

		/*Get the height of the screen*/
		int height = GetSystemMetrics(SM_CYSCREEN);

		/*Change the format of the back buffer to D3DFMT_X8R8G8B8*/
		m_D3Dpp.BackBufferFormat = D3DFMT_X8R8G8B8;

		/*Set the back buffer height to the height of the screen*/
		m_D3Dpp.BackBufferHeight = height;

		/*Set the back buffer width to the width of the screen*/
		m_D3Dpp.BackBufferWidth = width;

		/*Set the bool saying whether we are in windowed mode or not to false*/
		m_D3Dpp.Windowed = false;

		/*Change window style to support full screen*/
		SetWindowLongPtr(m_D3Dpp.hDeviceWindow,GWL_STYLE,WS_POPUP);

		/*To get the change to take effect must call setWindowPos*/
		SetWindowPos(m_D3Dpp.hDeviceWindow, HWND_TOP,0,0,width,height,SWP_NOZORDER | SWP_SHOWWINDOW);
	}
	/*If we want to go to windowed mode*/
	else
	{
		/*Check to see if we are already in windowed mode*/
		if(m_D3Dpp.Windowed)
		{
			/*If we are then our work is done*/
			return;
		}

		/*Create a rectangle starting at left = 0, right = width, top = 0, bottom = height*/
		RECT R = {0,0,m_Width,m_Height};

		/*Adjust the rectangle of the window we are using to the rectangle we just created*/
		AdjustWindowRect(&R, WS_OVERLAPPEDWINDOW, false);

		/*Change the format of the back buffer to D3DFMT_X8R8G8B8*/
		m_D3Dpp.BackBufferFormat = D3DFMT_X8R8G8B8;

		/*Set the back buffer height to the height of the window*/
		m_D3Dpp.BackBufferHeight = m_Height;

		/*Set the back buffer width to the width of the window*/
		m_D3Dpp.BackBufferWidth = m_Width;

		/*Set the bool saying whether we are in windowed mode or not to true*/
		m_D3Dpp.Windowed = true;

		/*Change window style to support windowed*/
		SetWindowLongPtr(m_D3Dpp.hDeviceWindow,GWL_STYLE,WS_OVERLAPPEDWINDOW);

		/*To get the change to take effect must call setWindowPos*/
		SetWindowPos(m_D3Dpp.hDeviceWindow, HWND_TOP,100,100,R.right,R.bottom,SWP_NOZORDER | SWP_SHOWWINDOW);

		/*Our device has been lost call the all of our objects on lost device functions*/
		onLostDevice();

		/*Reset our device using the presentation parameters*/
		m_pD3DDevice->Reset(&m_D3Dpp);

		/*Call all of our objects on reset device since our device has been reset*/
		onResetDevice();
	}
}

/*The function that will call all of the other functions needed for when we lose our device*/
void Framework::onLostDevice()
{
	/*Release the Font*/
	m_Font->OnLostDevice();

	/*Release effect 1*/
	m_pD3DEffect->OnLostDevice();//effect1

	/*TO BE ADDED: Things that need to be released when the device is lost and needs to be reset*/
}

/*The function that will call all of the other reset functions needed for when we recovered our device*/
void Framework::onResetDevice()
{
	/*Reset the Font*/
	m_Font->OnResetDevice();

	/*Reset effect 1*/
	m_pD3DEffect->OnResetDevice();//effect 1

	/*TO BE ADDED: Things that need to be initialized again when the device is reset*/
}

/*The function that checks whether we have lost our device or not*/
bool Framework::lostDevice()
{
	/*Test how cooperative our device is*/
	HRESULT	hr = m_pD3DDevice->TestCooperativeLevel();

	/*If the device is lost and cannot be reset then wait*/
	if(hr == D3DERR_DEVICELOST)
	{
		/*Wait 20 milliseconds*/
		Sleep(20);

		/*Return that we have lost our device*/
		return true;
	}

	/*If there is an error exit*/
	else if(hr == D3DERR_DRIVERINTERNALERROR)
	{
		/*Tell the user that something within is the cause*/
		MessageBox(0,L"Internal Driver Error\t\tExiting",0,0);

		/*Send the quit message to get out of the loop*/
		PostQuitMessage(0);

		/*Return that we have lost our device*/
		return true;
	}

	/*If the device is lost but can be reset*/
	else if(hr == D3DERR_DEVICENOTRESET)
	{
		/*Release the onjects that require to be released on lost device*/
		onLostDevice();

		/*Reset the device using our presentation parameters*/
		m_pD3DDevice->Reset(&m_D3Dpp);

		/*Initialize the objects to what they were upon the reset*/
		onResetDevice();

		/*Return that we haven't lost the device*/
		return false;
	}

	/*The device isn't lost at all*/
	else 
	{
		/*Return that we haven't lost the device*/
		return false;
	}
}

/*The function that will release everything that needs to be released*/
void Framework::Shutdown()
{
	/*Release all of the effects outside of objects*/
	releaseEffects();

	/*Release all of the meshes outside of objects*/
	releaseMeshes();

	/*Release all of the textures outside of objects*/
	releaseTextures();
	
	/*Delete the input device and release anything within it*/
	delete m_Input;
	m_Input = 0;

	/*Release our Font*/
	SAFE_RELEASE(m_Font);

	/*Release our direct 3d device*/
	SAFE_RELEASE(m_pD3DDevice);

	/*Release our direct 3d object*/
	SAFE_RELEASE(m_pD3DObject);
}

/*The function that will release all of the meshes that we are going to be using not within any object*/
void Framework::releaseEffects()
{
	SAFE_RELEASE(m_pD3DEffect);//effect 1
	SAFE_RELEASE(m_pD3DEffectError);
}

/*The function that will release all of the meshes that we are going to be using not within any object*/
void Framework::releaseMeshes()
{
	SAFE_RELEASE(m_pSphereMesh);//mesh 1
}

/*The function that will release all of the textures that we are going to be using not within any object*/
void Framework::releaseTextures()
{
	SAFE_RELEASE(m_Grass0Texture);//texture 1
}	

/*The function that will reset all of the values used within our game/framework*/
void Framework::restart()
{
}

/*The function that will tell us if we have had collision or not*/
bool Framework::checkCollision(int i)
{
	return false;
}
